<template>
  <div ref="codeEditorRef" class="code-editor"></div>
</template>
<script setup name="CodeEditor">
import * as monaco from "monaco-editor";
import { initializeMonacoWorkers } from "./monacoWorkers";

const { proxy } = getCurrentInstance();

// 定义组件的属性
const props = defineProps({
  modelValue: String,
  language: {
    type: String,
    default: "json",
  },
  theme: {
    type: String,
    default: "vs",
  },
  readOnly: {
    type: Boolean,
    default: false,
  },
});

let editor;
const emit = defineEmits(["update:modelValue", "change", "editor-mounted"]);

watch(
  () => props.modelValue,
  (newValue) => {
    if (newValue !== editor?.getValue()) {
      // 使用 nullish coalescing 运算符处理 undefined 和 null
      editor.setValue(newValue ?? "");
    }
  }
);

watch(
  () => props.readOnly,
  (newReadOnly) => {
    editor.updateOptions({ readOnly: newReadOnly });
  }
);

onMounted(() => {
  if (proxy.$refs.codeEditorRef && !editor) {
    editor = monaco.editor.create(proxy.$refs.codeEditorRef, {
      value: props.modelValue,
      language: props.language,
      theme: props.theme,
      readOnly: props.readOnly,
      selectOnLineNumbers: true,
      renderSideBySide: false,
      automaticLayout: true, // 自动布局
    });
    editor.onDidChangeModelContent(() => {
      const currentValue = editor.getValue();
      emit("update:modelValue", currentValue);
      emit("change", currentValue);
    });
    emit("editor-mounted", editor);
  }
  initializeMonacoWorkers();
});

onBeforeUnmount(() => {
  cleanup();
});

// 这个函数可以由父组件调用来进行清理
function cleanup() {
  if (editor) {
    editor.dispose();
  }
}
</script>
<style scoped>
.code-editor {
  width: 100%;
  height: 300px;
  box-shadow: 0 0 0 1px var(--el-input-border-color, var(--el-border-color));
}
</style>
